package cn.kt.mywxdemo.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.kt.mywxdemo.message.Article;
import cn.kt.mywxdemo.message.NewsMessage;
import cn.kt.mywxdemo.message.TextMessage;
import cn.kt.mywxdemo.utils.WordUtil;
import com.baidu.aip.ocr.AipOcr;
import com.thoughtworks.xstream.XStream;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Created by tao.
 * Date: 2023/3/7 10:26
 * 描述:
 */
@RestController
public class WxController {

    public static final String APP_ID = "25524899";
    public static final String API_KEY = "IAKeziT8OmX2yE5Y55gfHdNw";
    public static final String SECRET_KEY = "GoC65d2k01Duu89IaGMF1wmTOVp4qVya";

    @GetMapping("/hello")
    public String hello() {
        return "hello wechat";
    }


    /**
     * 服务器接入微信公众平台
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     */
    @GetMapping("/")
    public String check(String signature,
                        String timestamp,
                        String nonce,
                        String echostr) {

        // 1）将token、timestamp、nonce三个参数进行字典序排序
        String token = "1205529635";
        List<String> list = Arrays.asList(token, timestamp, nonce);
        //排序
        Collections.sort(list);
        // 2）将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : list) {
            stringBuilder.append(s);
        }

        //加密
        try {
            MessageDigest instance = MessageDigest.getInstance("sha1");
            //使用sha1进行加密，获得byte数组
            byte[] digest = instance.digest(stringBuilder.toString().getBytes());
            StringBuilder sum = new StringBuilder();
            for (byte b : digest) {
                sum.append(Integer.toHexString((b >> 4) & 15));
                sum.append(Integer.toHexString(b & 15));
            }
            // 3）开发者获得加密后的字符串可与 signature 对比，标识该请求来源于微信
            if (!StrUtil.isEmptyIfStr(signature) && signature.equals(sum.toString())) {
                return echostr;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 接收用户消息
     *
     * @param request
     * @return
     * @throws IOException
     */
    @PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException {
        // 将消息封装成map
        ServletInputStream inputStream = request.getInputStream();
        byte[] bytes = IoUtil.readBytes(inputStream);
        Map<String, Object> map = XmlUtil.xmlToMap(new String(bytes));
        System.out.println(map);

        //回复消息
        String msgType = map.get("MsgType").toString();
        String message = "";
        switch (msgType) {
            case "text":
                //回复同义词
                if ("图文".equals(map.get("Content"))) {
                    message = getReplyNewsMessage(map);
                } else {
                    message = getReplyMessageByWord(map);
                }
                break;
            case "event":
                message = handleEvent(map);
                break;
            case "image":
                message = handleImage(map);
                break;
            default:
                break;

        }
        return message;

    }


    /**
     * 获得回复的消息内容
     *
     * @param map
     * @return xml格式的字符串
     */
    private String getReplyMessage(Map<String, Object> map) {

        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName").toString());
        textMessage.setFromUserName(map.get("ToUserName").toString());
        textMessage.setMsgType("text");
        textMessage.setContent("欢迎关注本公众号！");
        textMessage.setCreateTime(System.currentTimeMillis() / 1000);

        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }

    /**
     * 获得同义词
     *
     * @param map
     * @return xml格式的字符串
     */
    private String getReplyMessageByWord(Map<String, Object> map) {

        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName").toString());
        textMessage.setFromUserName(map.get("ToUserName").toString());
        textMessage.setMsgType("text");
        String content = WordUtil.getWords(map.get("Content").toString());
        textMessage.setContent(content);

        textMessage.setCreateTime(System.currentTimeMillis() / 1000);

        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }


    /**
     * 获得图文消息
     *
     * @param map
     * @return xml格式的字符串
     */
    private String getReplyNewsMessage(Map<String, Object> map) {
        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setToUserName(map.get("FromUserName").toString());
        newsMessage.setFromUserName(map.get("ToUserName").toString());
        newsMessage.setMsgType("news");
        newsMessage.setCreateTime(System.currentTimeMillis() / 1000);
        newsMessage.setArticleCount(1);
        List<Article> articles = new ArrayList<>();
        Article article = new Article();
        article.setTitle("左眼会陪右眼哭の博客");
        article.setDescription("干嘛这么想不开，要在脸上贴个输字！");
        article.setUrl("https://qkongtao.cn/");
        article.setPicUrl("https://upyun.qkongtao.cn/chevereto/2022/09/29/logo.png");
        articles.add(article);
        newsMessage.setArticles(articles);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(NewsMessage.class);
        String xml = xStream.toXML(newsMessage);
        return xml;
    }


    /**
     * 处理事件推送
     *
     * @param map
     * @return
     */
    private String handleEvent(Map<String, Object> map) {
        String event = map.get("Event").toString();
        switch (event) {
            case "CLICK":
                if ("1".equals(map.get("EventKey").toString())) {
                    TextMessage textMessage = new TextMessage();
                    textMessage.setToUserName(map.get("FromUserName").toString());
                    textMessage.setFromUserName(map.get("ToUserName").toString());
                    textMessage.setMsgType("text");
                    textMessage.setContent("你点击了event key是1的按钮");
                    textMessage.setCreateTime(System.currentTimeMillis() / 1000);
                    //XStream将Java对象转换成xml字符串
                    XStream xStream = new XStream();
                    xStream.processAnnotations(TextMessage.class);
                    String xml = xStream.toXML(textMessage);
                    return xml;
                }
                break;
            case "VIEW":
                System.out.println("view");
                break;
            // 用户已关注触发
            case "SCAN":
                System.out.println("SCAN");
                break;
            // 用户未关注，点击关注后触发
            case "subscribe":
                System.out.println("subscribe");
                break;
            default:
                break;

        }
        return null;
    }

    /**
     * 图片文字识别处理
     *
     * @param map
     * @return
     */
    private String handleImage(Map<String, Object> map) {
        // 初始化一个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        // 网络图片文字识别, 图片参数为远程url图片
        String url = map.get("PicUrl").toString();
        JSONObject res = client.webImageUrl(url, new HashMap<String, String>());
        //解析内容，生成返回的数据
        JSONArray wordsResult = res.getJSONArray("words_result");
        StringBuilder stringBuilder = new StringBuilder();
        Iterator<Object> iterator = wordsResult.iterator();
        while (iterator.hasNext()) {
            JSONObject jsonObject = (JSONObject) iterator.next();
            stringBuilder.append(jsonObject.getString("words") + " ");
        }
        return createTextMessage(stringBuilder.toString(), map);
    }

    private String createTextMessage(String content, Map<String, Object> map) {
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName").toString());
        textMessage.setFromUserName(map.get("ToUserName").toString());
        textMessage.setMsgType("text");
        textMessage.setContent(content);
        textMessage.setCreateTime(System.currentTimeMillis() / 1000);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }
}